﻿namespace ReplayDataFile
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Runtime.CompilerServices;

    public class BlockFileHeader
    {
        private const long FILEFLAG = 0x7a7a666d73636868L;
        public List<TimeSegment> TimeSegments = new List<TimeSegment>();

        public BlockFileHeader()
        {
            this.FileFlag = 0x7a7a666d73636868L;
            this.FileVersion = 1;
            this.RecordNo = 1L;
        }

        public bool FromByteBuffer(byte[] buf)
        {
            if (buf.Length < Size)
            {
                return false;
            }
            try
            {
                BinaryReader reader = new BinaryReader(new MemoryStream(buf));
                this.FileFlag = reader.ReadInt64();
                uint num = reader.ReadUInt32();
                if (this.FileFlag != 0x7a7a666d73636868L)
                {
                    return false;
                }
                if (num != CRC32.CalcCRC32(buf, 12, buf.Length - 12))
                {
                    return false;
                }
                this.FileVersion = reader.ReadInt32();
                this.FileId = reader.ReadUInt32();
                this.DataRecordFormatVersion = reader.ReadInt32();
                this.BlockCount = reader.ReadInt32();
                this.BlockSize = reader.ReadInt32();
                this.DataTypeDirSize = reader.ReadInt32();
                this.BlockAllocTableSize = reader.ReadInt32();
                int num2 = reader.ReadInt32();
                this.RecordNo = reader.ReadInt64();
                this.FirstRecordNo = reader.ReadInt64();
                this.TimeSegments.Clear();
                for (int i = 0; i < num2; i++)
                {
                    TimeSegment item = new TimeSegment {
                        BeginTime = new DateTime(reader.ReadInt64()),
                        BeginRecordNo = reader.ReadInt64(),
                        EndTime = new DateTime(reader.ReadInt64()),
                        EndRecordNo = reader.ReadInt64()
                    };
                    this.TimeSegments.Add(item);
                }
                this.FilePurpose = reader.ReadInt32();
            }
            catch (Exception exception)
            {
                Trace.WriteLine(string.Format("BlockFile file header parse error: {0}", exception.Message));
                return false;
            }
            return true;
        }

        public byte[] ToByteBuffer()
        {
            try
            {
                byte[] buffer = new byte[Size];
                BinaryWriter writer = new BinaryWriter(new MemoryStream(buffer));
                writer.Write(this.FileFlag);
                writer.Write(0);
                writer.Write(this.FileVersion);
                writer.Write(this.FileId);
                writer.Write(this.DataRecordFormatVersion);
                writer.Write(this.BlockCount);
                writer.Write(this.BlockSize);
                writer.Write(this.DataTypeDirSize);
                writer.Write(this.BlockAllocTableSize);
                writer.Write(this.TimeSegments.Count);
                writer.Write(this.RecordNo);
                writer.Write(this.FirstRecordNo);
                int num = 0;
                foreach (TimeSegment segment in this.TimeSegments)
                {
                    writer.Write(segment.BeginTime.Ticks);
                    writer.Write(segment.BeginRecordNo);
                    writer.Write(segment.EndTime.Ticks);
                    writer.Write(segment.EndRecordNo);
                    if (++num >= this.MaxTimeSegmentCount)
                    {
                        break;
                    }
                }
                writer.Write(this.FilePurpose);
                uint num2 = CRC32.CalcCRC32(buffer, 12, buffer.Length - 12);
                writer.BaseStream.Seek(8L, SeekOrigin.Begin);
                writer.Write(num2);
                return buffer;
            }
            catch (Exception exception)
            {
                Trace.WriteLine(string.Format("BlockFile file header pack error: {1}", exception.Message));
                return null;
            }
        }

        public int BlockAllocTableSize { get; set; }

        public int BlockCount { get; set; }

        public int BlockSize { get; set; }

        public int DataRecordFormatVersion { get; set; }

        public int DataTypeDirSize { get; set; }

        public long FileFlag { get; set; }

        public uint FileId { get; set; }

        public int FilePurpose { get; set; }

        public int FileVersion { get; set; }

        public long FirstRecordNo { get; set; }

        public int MaxTimeSegmentCount
        {
            get
            {
                return ((Size - 0x100) / 0x20);
            }
        }

        public long RecordCount
        {
            get
            {
                return (this.RecordNo - this.FirstRecordNo);
            }
        }

        public long RecordNo { get; set; }

        public static int Size
        {
            get
            {
                return 0x800;
            }
        }
    }
}

